package online.hxstar.learn.nio.bio2;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author huxing
 * @date 2018-12-13 11:05
 * @describe 线程工厂构建类
 */
public class ThreadFactoryBuilder {


    private String namePrefix = null;
    private boolean daemon = false;
    private int priority = Thread.NORM_PRIORITY;

    /**
     * 构建线程前缀
     *
     * @param namePrefix 前缀
     */
    public ThreadFactoryBuilder setNamePrefix(String namePrefix) {
        if (namePrefix == null) {
            throw new NullPointerException("名称前缀为空");
        }
        this.namePrefix = namePrefix;
        return this;
    }

    /**
     * 设置守护线程
     *
     * @param daemon tree false
     */
    public ThreadFactoryBuilder setDaemon(boolean daemon) {
        this.daemon = daemon;
        return this;
    }

    /**
     * 设置线程优先级
     *
     * @param priority 优先级
     */
    public ThreadFactoryBuilder setPriority(int priority) {
        if (priority < Thread.MIN_PRIORITY) {
            throw new IllegalArgumentException(String.format(
                    "Thread priority (%s) must be >= %s", priority, Thread.MIN_PRIORITY));
        }
        if (priority > Thread.MAX_PRIORITY) {
            throw new IllegalArgumentException(String.format(
                    "Thread priority (%s) must be <= %s", priority, Thread.MAX_PRIORITY));
        }
        this.priority = priority;
        return this;
    }

    /**
     * 构建线程
     */
    public ThreadFactory build() {
        return build(this);
    }

    /**
     * 构建线程
     *
     * @param builder 构建参数
     * @return 构建结果
     */
    private static ThreadFactory build(ThreadFactoryBuilder builder) {
        final String namePrefix = builder.namePrefix;
        final boolean daemon = builder.daemon;
        final int priority = builder.priority;
        final AtomicLong count = new AtomicLong(0);
        return (Runnable runnable) -> {
            Thread thread = new Thread(runnable);
            thread.setDaemon(daemon);
            thread.setPriority(priority);
            if (namePrefix != null) {
                thread.setName(namePrefix + "-" + count.getAndIncrement());
            }
            return thread;
        };
    }
}
